package com.AdvancedDemos.集合.双列集合;

import java.util.*;

public class LearnMap {
    public static void main(String[] args) {
        /**
         * Map 集合是双列集合,每个元素都是成双成对的,每个元素都是"key - value"称为一个键值对/键值对对象/一个entry对象,Map集合也被称为键值对集合
         * Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值
         * 当需要存储一一对应的数据时,就可以考虑使用Map集合来做
         *
         *Map集合体系结构
         *接口                        Map<K,V>
         *                       ↙      ↓      ↘
         *实现类      HashMap<K,V>       ...     TreeMap<K,V>
         *                ↓
         *         LinkedHashMap<K,V>
         *
         * Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的
         *
         * ◉ HashMap(由键决定特点):无序,不重复,无索引 (用的最多)
         * ◉ LinkedHashMap(由键决定特点):有序,不重复,无索引
         * ◉ TreeMap(由键决定特点):按照大小默认升序排序,不重复,无索引
         */

        Map<String, Integer> map = new HashMap<>();//父类变量接子类对象
        map.put("手表", 100);
        map.put("手表", 220);//后面键重复的数据会覆盖前面的数据
        map.put("手机", 2);
        map.put("Java", 2);
        map.put(null, null);//可以键值对都是null
        System.out.println(map);//{null=null, 手表=220, Java=2, 手机=2}

        map = new LinkedHashMap<>();
        map.put("手表", 100);
        map.put("手表", 220);//后面键重复的数据会覆盖前面的数据
        map.put("手机", 2);
        map.put("Java", 2);
        map.put(null, null);//可以键值对都是null
        System.out.println(map);//{手表=220, 手机=2, Java=2, null=null} 有序

        Map<Integer, String> map1 = new TreeMap<>();
        map1.put(23, "Java");
        map1.put(23, "MySQL");//后面键重复的数据会覆盖前面的数据
        map1.put(19, "李四");
        map1.put(20, "王五");
        System.out.println(map1);//{19=李四, 20=王五, 23=MySQL} 默认按照键升序


        System.out.println("---------------");
        map = new HashMap<>();
        map.put("手表", 100);
        map.put("手表", 220);
        map.put("手机", 2);
        map.put("Java", 2);
        map.put(null, null);
        System.out.println(map);//{null=null, 手表=220, Java=2, 手机=2}

        //1.public int size() 获取集合的大小
        System.out.println(map.size());//4

        //2.public void clear() 清空集合
//        map.clear();
//        System.out.println(map);//{}

        //3.public boolean isEmpty(); 判断集合是否为空,空则返回true,否则false
        System.out.println(map.isEmpty());//true

        //4.public V get(Object key) 根据键获取对应值
        Integer i1 = map.get("手表");
        System.out.println(i1);//220
        System.out.println(map.get("手机"));//2
        System.out.println(map.get("张三"));//null  当get map中不存在的键时,返回null

        //5.public V remove(Obejct key) 根据键删除整个键值对,并返回键对应的值
        Integer 手表 = map.remove("手表");
        System.out.println(map);//{null=null, Java=2, 手机=2}
        System.out.println(手表);//220

        //6.public boolean containsKey(Object key) 判断是否包含某个键值,包含返回true,否则返回false
        System.out.println(map.containsKey("手表"));//false
        System.out.println(map.containsKey("手机"));//true
        System.out.println(map.containsKey("java"));//false
        System.out.println(map.containsKey("Java"));//true

        //7.public boolean containsValue(Object value)  判断是否包含某个值
        System.out.println(map.containsValue(2));//true
        System.out.println(map.containsValue("2"));//false

        //8.public Set<K> keySet(); 获取map集合的全部键
        Set<String> keys = map.keySet();//keySet()返回的是一个Map的内部类KeySet类的对象,它是Set接口的实现类
        System.out.println(keys);//[null, Java, 手机]
        /*Map类对象的keySet()返回的是一个Set对象引用,而不是一份拷贝,如果对返回值进行操作,会影响Map对象,
         * 例如:
         * Map<Object,Object> map = HashMap<Object,Object>();
         * map.put("1","aaa");
         * map.put("2","bbb");
         * map.put("3","ccc");
         * Set<Object> set = map.keySet();
         * set.remove("1");
         * map.get("1");//返回null
         * 所以,如果想得到一个独立的键集合的话,使用new HashSet<>(map.keySet())深拷贝即可
         * */


        //9.public Collection<V> values() 获取map集合的全部值
        Collection<Integer> values = map.values();
        System.out.println(values);//[null, 2, 2]
        /*与上面的keySet()类似,values()返回的是一个Collection对象引用,而不是一份拷贝,如果对返回值进行操作,会影响Map对象,*/

        //10.putAll 把其他map集合中的数据倒入到自己集合中来
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("java1", 10);
        map2.put("java2", 20);
        Map<String, Integer> map3 = new HashMap<>();
        map3.put("java3", 10);
        map3.put("java2", 222);
        map2.putAll(map3);//把map3集合中的元素,全部倒入map2中
        System.out.println(map2);//{java3=10, java2=222, java1=10} 键重复的,会被后添加的覆盖
        System.out.println(map3);//{java3=10, java2=222} map3自身不变


    }
}
